package com.edu.shiro.shiroconfig;

import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.edu.shiro.domain.SysUser;
import com.edu.shiro.service.RoleService;
import com.edu.shiro.service.SysMenuService;
import com.edu.shiro.service.SysUserService;

public class UserRealm extends AuthorizingRealm {
	
	private Logger logger = LoggerFactory.getLogger(UserRealm.class);
	
	@Autowired
	private SysUserService userService;
	
	@Autowired
	private RoleService roleService;
	
	@Autowired
	private SysMenuService sysMenuService;
	
	/**
	 * 配置权限  注入权限
	 * @param principals
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		SysUser user = (SysUser) principals.getPrimaryPrincipal();
		logger.info("设置权限");
		Set<String> roles = roleService.selectRoleKeys(user.getUserId());
        Set<String> menus = sysMenuService.selectPermsByUserId(user.getUserId());
        // 角色加入AuthorizationInfo认证对象
        simpleAuthorizationInfo.setRoles(roles);
        // 权限加入AuthorizationInfo认证对象
        simpleAuthorizationInfo.setStringPermissions(menus);
		return simpleAuthorizationInfo;
	}
	
	/**
	 * 登录验证
	 * @param token账户数据
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		//获取用户输入的账号
		String username = (String)token.getPrincipal();
//		FormAuthenticationFilter
		//获取密码
		String pwd =new String((char[])token.getCredentials());
		logger.info("登录验证");
		SysUser user = userService.getSysUserByname(username);
		if(null == user){
			throw new UnknownAccountException();
		}
//		if(!pwd.equals(user.getSalt())){
//			throw new IncorrectCredentialsException();
//		}
		if("1".equals(user.getStatus())){
			throw new LockedAccountException();
		}
		
		//调用CredentialsMatcher 校验 还需要创建一个类继承CredentialsMatcher 如果在上面校验，就不需要了
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user,user.getSalt().toCharArray(),getName());
		return simpleAuthenticationInfo;
	}
	
	
	/**
	 * 重写方法,清除当前用户的 认证缓存
	 * @param principals
	 */
	@Override
	protected void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}
	
	/**
	 * 重写方法,清除当前用户的 授权缓存
	 * @param principals
	 */
	@Override
	protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}
	
	@Override
	protected void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}
	
	/**
	 * 自定义方法：清除所有 授权缓存
	 */
	public void clearAllCachedAuthorizationInfo(){
		getAuthorizationCache().clear();
	}
	
	/**
	 * 自定义方法：清除所有 认证缓存
	 */
	public void clearAllCachedAuthenticationInfo(){
		getAuthenticationCache().clear();
	}
	
	/**
	 * 自定义方法：清除所有的  认证缓存  和 授权缓存
	 */
	public void clearAllCache() {
	    clearAllCachedAuthenticationInfo();
	    clearAllCachedAuthorizationInfo();
	}


}
